﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using _InformaticaIndustrial_DerivdosVinicos.DTO;
using Dao;

namespace _InformaticaIndustrial_DerivdosVinicos.Interfaz
{
    public partial class PuntodeEquilibrio : Form
    {
        MateriaPrima _mpEntity;
        Componente _compEntity;
        RutaFabricacion _rfEntity;
        RF_CT _rf_ct;
        CentroTrabajo _ctrabajo;
        double ctoTotalMP;
        double tarifaTotalMO;
        double gtoTotalFabricacion;
        double ctoTotalComponentes;
        IPRutaFabricacion _ipRutaFab = new IPRutaFabricacion();
        IPCentroTrabajo _ipCentroTrabajo = new IPCentroTrabajo();
        IPCostoVariable _ipCostoVariable = new IPCostoVariable();
        IList<RF_CT> rf_ctList = new List<RF_CT>();
        IList<CentroTrabajo> _ctList;
        CostosVariable _costoVariable;
        IList<EstructuraProducto> epList;

        DTOEquivalencias dtoEquiv;
        IList<DTOEquivalencias> dtoList = new List<DTOEquivalencias>();
        Producto p;
        IList<Producto> productosTerminadosList = new IPProducto().getAll<Producto>();

        public PuntodeEquilibrio()
        {
            InitializeComponent();
            cbProducto.DataSource = productosTerminadosList;
        }

        private void btCalcular_Click(object sender, EventArgs e)
        {
            float totalCF = 0;
            double it = 0;
            double totalCvEstandar = 0;
            double totalCvEquivalencia = 0;
            double cvUnit = 0;
            double cantEquilibrio = 0;
            double precioEquilibrio = 0;
            double ctoVariableEstandar = 0;
            IList<Demanda> demListProdEquivalencia;
            try
            {
                IList<CostoFijo> cfList = new IPCostoFijo().getAll<CostoFijo>().Where(cf => cf.Activo == true).ToList();

                foreach (var item in cfList)
                {
                    totalCF += (float) item.costo;
                }

                p = (Producto)cbProducto.SelectedItem;
                int idProdEst = Convert.ToInt16(cbProducto.SelectedValue);

                 IList<Demanda> demList = new IPDemandaCGI().getCriterioById<Demanda>("", "", idProdEst);//Demanda para el P.E

                 if (demList.Count > 0)
                 {
                     Demanda dem = demList.OrderByDescending(d => d.periodo).First();

                     it = (double)(dem.demandaReal * p.PrecioBase);
                     totalCvEstandar = (double)(CalcularCtoVariable(idProdEst) * dem.demandaReal); // Calcula el CV Total para el prod. estandar

                     cvUnit = (double)(totalCvEstandar / dem.demandaReal);
                     cantEquilibrio = (double)(totalCF / (p.PrecioBase - cvUnit));
                     //precioEquilibrio = (double)(cantEquilibrio * p.PrecioBase);
                     precioEquilibrio = (double)(totalCF / (1 - (totalCvEstandar / it)));
                     //productosTerminadosList.RemoveAt(cbProducto.SelectedIndex);

                    // dtoEquiv = new DTOEquivalencias();

                     foreach (var item in productosTerminadosList)
                     {
                         if (item.IdProducto != idProdEst)
                         {
                            //totalCvEquivalencia = 0;
                            dtoEquiv = new DTOEquivalencias();

                            demListProdEquivalencia = new IPDemandaCGI().getCriterioById<Demanda>("", "", item.IdProducto); //Demanda para las equiv

                            if (demListProdEquivalencia.Count >0)
                            {
                                Demanda demEquiv = demListProdEquivalencia.OrderByDescending(d => d.periodo).First();

                                totalCvEquivalencia = (double)(CalcularCtoVariable(item.IdProducto) * demEquiv.demandaReal); // Calcula el CV Total para el prod. equiv; // (double)(totalCvEstandar / dem.demandaReal); //CVunit para el Prod. Estandar

                                //totalCvEquivalencia = CalcularCtoVariable(item.IdProducto);

                                dtoEquiv.equivalencia = System.Math.Round((totalCvEquivalencia / totalCvEstandar), 2).ToString();
                                dtoEquiv.nombreEquivalencia = item.NombreProducto;

                                // n += (totalCvEstandar / totalCvEquivalencia).ToString() + item.NombreProducto;
                                dtoList.Add(dtoEquiv); 
                            }
                         }
                     }

                     textBox1.Text = p.Medida.NombreMedida;
                    // textBox2.Text = "$";
                     txtCE.Text = System.Math.Round(cantEquilibrio, 2).ToString();
                     txtPE.Text = System.Math.Round(precioEquilibrio, 2).ToString();

                     ////////////
                     ////////////// VER 
                     /////////////
                     for (int i = 0; i < dtoList.Count; i++)
                     {
                         if (i == 0)
                         {
                             textBox4.Text += dtoList[i].nombreEquivalencia + " = " + dtoList[i].equivalencia + " (" + p.NombreProducto.ToString() + ")\n";
                         }
                         else
                         {
                             textBox5.Text += dtoList[i].nombreEquivalencia + " = " + dtoList[i].equivalencia + " (" + p.NombreProducto.ToString() + ")";
                         }
                     } 
                     ///////////////
                     /////////////////
                     /////////////////
                 }
                 else
                 {
                     MessageBox.Show("No existen demandas cargadas para este producto");
                 }
            }
            catch (Exception)
            {
                throw;
            }
        }

        private double CalcularCtoVariable(int IdProducto)
        {
            double totalCV = 0;
            double totalMO = 0;
            double totalGtoFab = 0;

            totalCV = CalcularCMP();
            totalMO = CalcularMO();
            totalGtoFab = CalcularGF();
            
            ctoTotalMP = 0;            
            ctoTotalComponentes = 0;
            gtoTotalFabricacion = 0;

            return totalCV =  (double) ((totalCV + totalMO + totalGtoFab) );/// ((epList.Count > 0) ? epList.First().CantidadAProducir : 1));
        }

        public double CalcularCMP()
        {
            double cvMP = 0;
            double compon = 0;

            try
            {
                int i = Convert.ToInt16(cbProducto.SelectedValue);

                epList = new IPEstructuraProducto().getByCriterio<EstructuraProducto>("", "", i.ToString());

                foreach (var item in epList)
                {
                    if (item.IdMateriaPrima != null)
                    {
                        _mpEntity = item.MateriaPrima; //;new IPMateriaPrima().GetMP(Convert.ToInt16(item.IdMateriaPrima));
                       cvMP = CalcularCtoMP(_mpEntity, item);
                    }
                    else
                    {
                        _compEntity = item.Componente;
                        compon = CalcularCtoComponente(_compEntity, item);
                    }
                }
                return (cvMP + compon);
            }
            catch (Exception)
            {
                throw;
            }
        }

        private double CalcularMO()
        {
            tarifaTotalMO = 0;

            try
            {
                _rfEntity = _ipRutaFab.getCriterioById<RutaFabricacion>("", "", Convert.ToInt16(cbProducto.SelectedValue)).First();

                rf_ctList = _rfEntity.RF_CTs;//_ipRutaFab.GetRF_CT(_rfEntity.IdRF);

                foreach (var item in rf_ctList)
                {
                    _ctrabajo = item.CentroTrabajo; //_ipCentroTrabajo.getById(item.IdCT);
                    tarifaTotalMO += (double)((item.hsPreparacion * _ctrabajo.TarifaPreparacion) + (item.hsTrabajo * _ctrabajo.TarifaMO * _ctrabajo.CantPersonas));
                }

                return tarifaTotalMO;
            }
            catch (Exception)
            {
                throw;
            }
        }

        private double CalcularGF()
        {
            gtoTotalFabricacion = 0;

            try
            {
                foreach (var item in rf_ctList)
                {
                    _ctrabajo = item.CentroTrabajo; //_ipCentroTrabajo.getById(item.IdCT);
                    gtoTotalFabricacion += (float)(_ctrabajo.TotalGtosFabricacion);
                }

                return gtoTotalFabricacion;
            }
            catch (Exception)
            {
                throw;
            }
        }

        public double CalcularCtoMP(MateriaPrima _mp, EstructuraProducto eprod)
        {
            if (_mp.IdMP == eprod.IdMateriaPrima) //
            {
                ctoTotalMP += Convert.ToDouble(_mpEntity.costo * (eprod.cantidadMP));
            }

            return ctoTotalMP;
        }

        public double CalcularCtoComponente(Componente _comp, EstructuraProducto eprod)
        {
            if (_comp.IdComponente == eprod.IdComponente) //
            {
                ctoTotalComponentes += Convert.ToDouble(_comp.costo * (eprod.cantidadPC));
            }

            return ctoTotalComponentes;
        }

        private void btCancelar_Click(object sender, EventArgs e)
        {
            this.Close();
        }

        private void btGuardar_Click(object sender, EventArgs e)
        {
            this.Close();
        }
    }
}

